/*#include "n-ary.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
*/
#include"../include/main.h"
//struct narytree *nroot=NULL;


int createroot(struct FileDescriptor *fd)
{

    nroot=(struct narytree *)malloc(sizeof(struct narytree));
    nroot->mydes=fd;
    nroot->leftsibling=NULL;
    nroot->child=NULL;
    nroot->rightsibling=NULL;
    nroot->parent=NULL;
    return 1;
}



int search_nary(char pathname[locationpath_size])
{
    struct narytree *temp,*newadd;
  //  searched_node=NULL;// added by vijay going to use in move file
    searched_Descriptor=NULL; //initialize the searched descriptors
    temp=nroot;
    if(temp==NULL) return 0;
    else
    {


        while(1)
        {


            if(strcmp(pathname,temp->mydes->locationfullpath)==0)
            {
                searched_Descriptor=temp->mydes;
             //   searched_node=temp;// added by vijay going to use in move file
                return 1;

            }

            else if(strncmp(pathname,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && (temp==nroot || pathname[strlen(temp->mydes->locationfullpath)]=='/'))
            {
                if(temp->child==NULL)
                {
                    // if(strcmp(pathname,temp->mydes->locationfullpath)==0)return 1;
                    // else
                    return 0;
                }

                else
                {
                    //if(strcmp(pathname,temp->mydes->locationfullpath)==0)return 1;
                    //else
                    temp=temp->child;
                }
            }
            else if(temp->rightsibling==NULL)
            {
//                if(strcmp(pathname,temp->mydes->locationfullpath)==0)return 1;
                //else
                return 0;
            }
            else if(temp->rightsibling!=NULL)
            {
                //if(strcmp(pathname,temp->mydes->locationfullpath)==0) return 1;
                //else
                temp=temp->rightsibling;
            }



        }
    }
}

int update_nary(struct FileDescriptor *fd)
{
    struct narytree *temp,*newadd;
    temp=nroot;
    if(temp==NULL) return 0;
    else
    {


        while(1)
        {


            if(strcmp(fd->locationfullpath,temp->mydes->locationfullpath)==0 && strcmp(temp->mydes->filetype,"dummy")==0)
            {
                temp->mydes=fd;

                return 1;
            }

            else if(strncmp(fd->locationfullpath,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && (temp==nroot || fd->locationfullpath[strlen(temp->mydes->locationfullpath)]=='/'))
            {
                if(temp->child==NULL)
                {
                    if(strcmp(fd->locationfullpath,temp->mydes->locationfullpath)==0 && strcmp(temp->mydes->filetype,"dummy")==0)
                    {
                        temp->mydes=fd;

                        return 1;
                    }
                    else return 0;
                }

                else
                {
                    if(strcmp(fd->locationfullpath,temp->mydes->locationfullpath)==0 && strcmp(temp->mydes->filetype,"dummy")==0)
                    {
                        temp->mydes=fd;

                        return 1;
                    }
                    else temp=temp->child;
                }
            }
            else if(temp->rightsibling==NULL)
            {
                if(strcmp(fd->locationfullpath,temp->mydes->locationfullpath)==0 && strcmp(temp->mydes->filetype,"dummy")==0)
                {
                    temp->mydes=fd;

                    return 1;
                }
                else return 0;
            }
            else if(temp->rightsibling!=NULL)
            {
                if(strcmp(fd->locationfullpath,temp->mydes->locationfullpath)==0 && strcmp(temp->mydes->filetype,"dummy")==0)
                {
                    temp->mydes=fd;

                    return 1;
                }
                else temp=temp->rightsibling;
            }



        }
    }
}

int insert_nary(struct FileDescriptor *fd)
{
    struct narytree *temp,*newadd;
    temp=nroot;

    while(1)
    {
        if(strncmp(fd->locationfullpath,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && (temp==nroot || fd->locationfullpath[strlen(temp->mydes->locationfullpath)]=='/'))
        {
            if(temp->child==NULL)
            {
                newadd=(struct narytree *)malloc(sizeof(struct narytree));
                temp->child=newadd;
                newadd->mydes=fd;
                newadd->child=NULL;
                newadd->rightsibling=NULL;
                newadd->leftsibling=NULL;
                newadd->parent=temp;
                return 1;
            }
            else
            {
                temp=temp->child;
            }
        }
        else if(temp->rightsibling==NULL && temp!=nroot)
        {
            newadd=(struct narytree *)malloc(sizeof(struct narytree));
            temp->rightsibling=newadd;
            newadd->mydes=fd;
            newadd->child=NULL;
            newadd->rightsibling=NULL;
            newadd->leftsibling=temp;
            if(temp->parent!=NULL)newadd->parent=temp->parent;
            else newadd->parent=NULL;
            return 1;


        }
        else if(temp->rightsibling!=NULL)
        {
            temp=temp->rightsibling;
        }
        else if(temp->rightsibling==NULL && temp==nroot)
        {
            return 0;
        }


    }




}


int print_nary(struct narytree *temp)
{
    int x=0;
    //struct narytree *temp;
    //temp=nroot;
    if(temp!=NULL)
    {
        print_nary(temp->child);
        printf("\n");
        printf("%s",temp->mydes->locationfullpath);
        //printf("             ");
       // printf("%d",temp->mydes->locationblocknumber);
       // printf("               ");
       // printf("%d",freelist[temp->mydes->locationblocknumber]);
        print_nary(temp->rightsibling);
        x=1;
    }
    return x;

}

int nonrecur_nary(struct narytree *temp, FILE *fp)
{
    int x=0;


    if(temp!=NULL)
    {
        fprintf(fp,"%s\t",temp->mydes->locationfullpath);


        nonrecur_nary(temp->rightsibling,fp);
        x=1;
    }

    return x;

}
int recur_nary(struct narytree *temp, FILE *fp)
{
    int x=0;

    if(temp!=NULL)
    {
        fprintf(fp,"%s",temp->mydes->locationfullpath);
        if(temp->rightsibling!=NULL) fprintf(fp,"\t");
        recur_nary(temp->rightsibling,fp);
        if(temp->child!=NULL) fprintf(fp,"\n");
        recur_nary(temp->child,fp);
        x=1;
    }


    return x;

}
/*int delete_nary(char pathname[300])
{
    struct narytree *temp,*newadd;
   temp=n-root;
   while(1)
   {

       if(strcmp(pathname,temp->mydes->locationfullpath)==0)
       {
           if((temp->child==NULL) && (temp->rightsibling==NULL) &&(temp->leftsibling==NULL) && (temp->parent==NULL)) free(temp);
           else if((temp->leftsibling==NULL) &&(temp->rightsibling==NULL) && (temp->child==NULL) && (temp->parent!=NULL))
           {
               temp->parent->child=NULL;
               free(temp);
           }
           else if((temp->leftsibling!=NULL) &&(temp->rightsibling==NULL) && (temp->child==NULL) )
           {
               temp->leftsibling->rightsibling=NULL;
               free(temp);
           }
       }

       else if(strncmp(pathname,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && pathname[strlen(temp->mydes->locationfullpath)]=='/')
       {
           if(temp->child==NULL)
           {
               if(strcmp(pathname,temp->mydes->locationfullpath)==0)return 1;
               else return 0;
           }

           else
           {
               if(strcmp(pathname,temp->mydes->locationfullpath)==0)return 1;
               else temp=temp->child;
           }
       }
       else if(temp->rightsibling==NULL)
       {
           if(strcmp(pathname,temp->mydes->locationfullpath)==0)return 1;
           else return 0;
       }
       else if(temp->rightsibling!=NULL)
       {
           if(strcmp(pathname,temp->mydes->locationfullpath)==0) return 1;
           else temp=temp->rightsibling;
       }



   }
}
*/

/*#define ERR_VFS_DELETEDIR_01 "CANNOT_FIND_SPECIFIED_PATH_OR_DIR"
#define ERR_VFS_DELETEDIR_02 "DIRECTORY_IS_NOT_EMPTY"
#define ERR_VFS_DELETEDIR_03 "INVALID_DIRNAME"*/
int delete_nary(char pathname[locationpath_size])// this delete directory is only for directories not for files
{

    struct narytree *temp,*newadd;
    temp=nroot;
    if(temp==NULL) return 0;
    else
    {

        if(strcmp(pathname,temp->mydes->locationfullpath)==0)// why??  cannot delete root
        {
            return 0;
        }
        else
        {


            while(1)
            {


                if(strncmp(pathname,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && (temp==nroot || pathname[strlen(temp->mydes->locationfullpath)]=='/'))
                {
                    if(temp->child==NULL)
                    {

                        printf("deletedir_FAILURE %s\n",ERR_VFS_DELETEDIR_01);
                            return 0;
                    }

                    else
                    {

                        temp=temp->child;
                    }
                }
                else if(temp->rightsibling==NULL && strcmp(pathname,temp->mydes->locationfullpath)!=0)
                {

                     printf("deletedir_FAILURE %s\n",ERR_VFS_DELETEDIR_01);
                            return 0;
                }
                else if(temp->rightsibling!=NULL && strcmp(pathname,temp->mydes->locationfullpath)!=0)
                {

                    temp=temp->rightsibling;
                }



                if(strcmp(pathname,temp->mydes->locationfullpath)==0)
                {


                    if(temp->child!=NULL)
                    {
                         printf("deletedir_FAILURE %s\n",ERR_VFS_DELETEDIR_02);
                            return 0;
                    }
                    else if((temp->parent!=NULL) && (temp->rightsibling==NULL) && (temp->leftsibling!=NULL))
                    {
                        struct narytree *tempo;
                        tempo=temp;
                        header.used_file_descriptors--;
                        freelist[temp->mydes->locationblocknumber]=0;

                        free_nary(tempo->child);
                        temp->leftsibling->rightsibling=NULL;
                        if(temp->child!=NULL)
                        {
                            temp->child->parent=NULL;
                        }

                        free(temp);
                        return 1;
                    }
                    else if((temp->parent!=NULL) && (temp->rightsibling!=NULL) && (temp->leftsibling!=NULL))
                    {
                        struct narytree *tempo;
                        tempo=temp;
                        header.used_file_descriptors--;
                        freelist[temp->mydes->locationblocknumber]=0;

                        free_nary(tempo->child);
                        temp->leftsibling->rightsibling=temp->rightsibling;
                        temp->rightsibling->leftsibling=temp->leftsibling;
                        if(temp->child!=NULL)
                        {
                            temp->child->parent=NULL;
                        }

                        free(temp);
                        return 1;
                    }
                    else if((temp->parent!=NULL) && (temp->rightsibling!=NULL) && (temp->leftsibling==NULL))
                    {
                        struct narytree *tempo;
                        tempo=temp;
                        header.used_file_descriptors--;
                        freelist[temp->mydes->locationblocknumber]=0;

                        free_nary(tempo->child);
                        temp->rightsibling->leftsibling=NULL;
                        temp->parent->child=temp->rightsibling;
                        if(temp->child!=NULL)
                        {
                            temp->child->parent=NULL;
                        }

                        free(temp);
                        return 1;
                    }
                    else if((temp->parent!=NULL) && (temp->rightsibling==NULL) && (temp->leftsibling==NULL))
                    {
                        struct narytree *tempo;
                        tempo=temp;
                        header.used_file_descriptors--;
                        freelist[temp->mydes->locationblocknumber]=0;

                        free_nary(tempo->child);
                        temp->parent->child=NULL;
                        if(temp->child!=NULL)
                        {
                            temp->child->parent=NULL;
                        }

                        free(temp);
                        return 1;
                    }


                }




            }
        }
    }
}

int free_nary(struct narytree *temp)
{
    int x=0;

    //temp=nroot;
    if(temp!=NULL)
    {
        free_nary(temp->child);
        //printf("%s\n",temp->mydes->locationfullpath);
        header.used_file_descriptors--;
        //printf("->%s",temp->mydes->locationfullpath);
        freelist[temp->mydes->locationblocknumber]=0;
        free_nary(temp->rightsibling);
        x=1;
    }
    return x;

}
int move_nary(struct narytree *n1)//similar to insert
{


    struct narytree *temp;


    temp=nroot;

    while(1)
    {

        if(strncmp(n1->mydes->locationfullpath,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && (temp==nroot || n1->mydes->locationfullpath[strlen(temp->mydes->locationfullpath)]=='/'))
        {

            if(temp->child==NULL)
            {
                //newadd=(struct narytree *)malloc(sizeof(struct narytree));
                temp->child=n1;
                //newadd->mydes=fd;
                //newadd->child=NULL;
                //newadd->rightsibling=NULL;
                //newadd->leftsibling=NULL;
                n1->parent=temp;
                insert_node(n1->mydes);
                if(n1->child!=NULL) movepath_nary(n1->child);

                return 1;


            }

            else
            {
                temp=temp->child;
            }
        }
        else if(temp->rightsibling==NULL && temp!=nroot)
        {
            //newadd=(struct narytree *)malloc(sizeof(struct narytree));
            temp->rightsibling=n1;
            //newadd->mydes=fd;
            //newadd->child=NULL;
            //newadd->rightsibling=NULL;
            n1->leftsibling=temp;
            if(temp->parent!=NULL)n1->parent=temp->parent;
            else n1->parent=NULL;
            insert_node(n1->mydes);
            if(n1->child!=NULL) movepath_nary(n1->child);
            return 1;


        }
        else if(temp->rightsibling!=NULL)
        {
            temp=temp->rightsibling;
        }
        else if(temp->rightsibling==NULL && temp==nroot)
        {
            return 0;
        }


    }




}

int movepath_nary(struct narytree *temp)
{
    int x=0;

    //temp=nroot;
    if(temp!=NULL)
    {
        delete_node(bst_root,temp->mydes->locationfullpath);
        strcpy(temp->mydes->locationfullpath,temp->parent->mydes->locationfullpath);
        strcat(temp->mydes->locationfullpath,"/");
        strcat(temp->mydes->locationfullpath,temp->mydes->filename);
        //call the insert of bst
        insert_node(temp->mydes);
        //insert_Into_HashTable(temp->mydes);
        movepath_nary(temp->child);
        //printf("%s\n",temp->mydes->locationfullpath);
        //header.used_file_descriptors--;
        //printf("->%s",temp->mydes->locationfullpath);
        //freelist[temp->mydes->locationblocknumber]=0;
        movepath_nary(temp->rightsibling);
        x=1;
    }
    return x;

}

//added by vijay called in move file
int delete_file_from_nary(char pathname[locationpath_size])// this delete directory is only for directories not for files
{
    struct narytree *temp;
    temp=nroot;
    while(1)
    {
        if(strncmp(pathname,temp->mydes->locationfullpath,strlen(temp->mydes->locationfullpath))==0 && (temp==nroot || pathname[strlen(temp->mydes->locationfullpath)]=='/'))
        {

            temp=temp->child;

        }

        else if(temp->rightsibling!=NULL && strcmp(pathname,temp->mydes->locationfullpath)!=0)
        {

            temp=temp->rightsibling;
        }

        if(strcmp(pathname,temp->mydes->locationfullpath)==0)
        {
            if((temp->parent!=NULL) && (temp->rightsibling==NULL) && (temp->leftsibling!=NULL))
            {
                temp->leftsibling->rightsibling=NULL;
                free(temp);
                return 1;
            }
            else if((temp->parent!=NULL) && (temp->rightsibling!=NULL) && (temp->leftsibling!=NULL))
            {
                temp->leftsibling->rightsibling=temp->rightsibling;
                temp->rightsibling->leftsibling=temp->leftsibling;
                free(temp);
                return 1;
            }
            else if((temp->parent!=NULL) && (temp->rightsibling!=NULL) && (temp->leftsibling==NULL))
            {
                temp->rightsibling->leftsibling=NULL;
                temp->parent->child=temp->rightsibling;
                free(temp);
                return 1;
            }
            else if((temp->parent!=NULL) && (temp->rightsibling==NULL) && (temp->leftsibling==NULL))
            {
                temp->parent->child=NULL;
                free(temp);
                return 1;
            }
        }
    }

}

